package com.lex.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.lex.common.annoatation.SysLog;
import com.lex.common.api.CommonResult;
import com.lex.common.enums.BusinessType;
import com.lex.entity.minio.BucketPolicyConfigDto;
import com.lex.entity.minio.MinioUploadDto;
import io.minio.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.shaded.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.lex.util.MyContext;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Controller
@Tag(name = "MinioController", description = "MinIO对象存储管理")
@RequestMapping("/minio")
public class MinioController {
    @Value("${minio.endpoint}")
    private String ENDPOINT;
    @Value("${minio.bucketName}")
    private String BUCKET_NAME;
    @Value("${minio.accessKey}")
    private String ACCESS_KEY;
    @Value("${minio.secretKey}")
    private String SECRET_KEY;

    @Operation(summary = "MinIO文件上传")
    @RequestMapping("/upload")
    @ResponseBody
    @SysLog(title = "MinIO文件上传", businessType = BusinessType.INSERT)
    public CommonResult upload(@RequestPart("file") MultipartFile files) {
        //Minio 支持多文件上传
//        List<MinioUploadDto> fileNames = new ArrayList<>();
        try {
            String username = MyContext.getCurrentUserName();
            //创建一个MinIO的Java客户端
            MinioClient minioClient =MinioClient.builder()
                    .endpoint(ENDPOINT)
                    .credentials(ACCESS_KEY,SECRET_KEY)
                    .build();
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
            if (isExist) {
                log.info("存储桶已经存在！");
            } else {
                //创建存储桶并设置只读权限
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build());
                BucketPolicyConfigDto bucketPolicyConfigDto = createBucketPolicyConfigDto(BUCKET_NAME);
                SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder()
                        .bucket(BUCKET_NAME)
                        .config(JSONUtil.toJsonStr(bucketPolicyConfigDto))
                        .build();
                minioClient.setBucketPolicy(setBucketPolicyArgs);
            }

//            for (MultipartFile file : files) {
            String filename = files.getOriginalFilename();
            String newFileName = genNewFileName(files.getOriginalFilename());
            //
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 设置存储对象名称
            String objectName = username + "/" + sdf.format(new Date()) + "/" + newFileName;
            // 使用putObject上传一个文件到存储桶中
            InputStream is = files.getInputStream();
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(BUCKET_NAME)
                    .object(objectName)
                    .contentType(files.getContentType())
                    .stream(is, files.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build();
            minioClient.putObject(putObjectArgs);
            //关闭文件流
            is.close();
            MinioUploadDto minioUploadDto = new MinioUploadDto();
            minioUploadDto.setName(filename);
            minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);
//                fileNames.add(minioUploadDto);
//            }
//            files.clone();
            return CommonResult.success(minioUploadDto);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("上传发生错误: {}！", e.getMessage());
        }
        return CommonResult.failed();
    }
    private String genNewFileName(String filename) {
        String filenameFormat = "%s.%s";
        return String.format(filenameFormat,
                UUID.randomUUID().toString().replace("-", "").substring(8),
                FilenameUtils.getExtension(filename)
        );

    }
    /**
     * 创建存储桶的访问策略，设置为只读权限
     */
    private BucketPolicyConfigDto createBucketPolicyConfigDto(String bucketName) {
        BucketPolicyConfigDto.Statement statement = BucketPolicyConfigDto.Statement.builder()
                .Effect("Allow")
                .Principal("*")
                .Action("s3:GetObject")
                .Resource("arn:aws:s3:::"+bucketName+"/*.**").build();
        return BucketPolicyConfigDto.builder()
                .Version("2012-10-17")
                .Statement(CollUtil.toList(statement))
                .build();
    }

    /**
     * 删除MinIO文件
     * "http://localhost:9000/monitor/20230914/微信图片_20230620091030.jpg"
     * 需要处理去掉"http://localhost:9000/monitor/"
     * objectName:文件存储路径 20230914/微信图片_20230620091030.jpg
     * @param objectName
     * @return
     */
    @Operation(summary = "MinIO文件删除")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    @SysLog(title = "MinIO文件删除", businessType = BusinessType.DELETE)
    public CommonResult delete(@RequestParam("objectName") String objectName) {
        try {
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(ENDPOINT)
                    .credentials(ACCESS_KEY,SECRET_KEY)
                    .build();
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build());
            return CommonResult.success(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.failed();
    }
}
